/*
 * @Author: yangzonglong
 * @Date: 2020-05-18 09:48:18
 * @version: v1.0.0
 * @Descripttion:
 * @LastEditors: yangzonglong
 * @LastEditTime: 2023-10-07 13:59:32
 * @Auditor:
 */
import axios, { AxiosRequestConfig as DefaultAxiosRequestConfig } from 'axios';
import qs from 'query-string';
import crypto from 'crypto-js';
import { error } from './../message/message';

interface AxiosRequestConfig extends DefaultAxiosRequestConfig {
  firstMessage?: boolean;
  errorMessage?: boolean;
}

export const TIMEOUT = 1000 * 60 * 2; // 默认2分钟超时
export const METHOD = 'POST';

export async function serverLoading(url: string, data: Record<string, any>, options?: AxiosRequestConfig) {
  return await server(url, data, options, true);
}

export default async function server(
  url: string,
  data: Record<string, any>,
  options?: AxiosRequestConfig,
  loading?: boolean
) {
  const _loading = typeof options === 'boolean' ? options : loading;

  try {
    if (_loading) window.$app.showLoading();
    const result = await axios(mergeOptions(url, data, options));
    if (_loading) window.$app.hideLoading();

    if (result.status === 200) {
      // http
      const data = result.data;
      if (data.status === 200) return data.result;

      const message = data.message || {};

      if (message.code === -11 && process.env.REACT_APP_ENV !== 'dev') {
        window.$app.showIsLoginFailure();
      }

      // eslint-disable-next-line
      throw { message: message.message, code: message.code };
    }
  } catch (errobj) {
    if (_loading) window.$app.hideLoading();

    const err = errobj as any;
    const message = typeof err === 'string' ? err : err?.message;

    if ((err?.code || err?.message) && options?.errorMessage !== false) {
      if (options?.firstMessage) error(message || err?.code);
      else error(err?.code || message, err);
    }

    throw err;
  }
}

export function mergeOptions(url: string, data: Record<string, any>, options?: AxiosRequestConfig) {
  const _options = options || {};
  _options.method = _options.method || METHOD;

  if (process.env.NODE_ENV !== 'development' && _options.method === 'POST' && localStorage.getItem('_') === null) {
    // 加密
    _options.data = {
      mode: 1,
      data: crypto.AES.encrypt(JSON.stringify(data), 'leo_scott_great').toString()
    };
  } else {
    _options[_options.method === 'GET' ? 'params' : 'data'] = data;
  }

  // _options.url = url + '?m=dev';
  _options.url = url + (process.env.NODE_ENV === 'development' ? (url.includes('?') ? '&=m=dev' : '?m=dev') : '');
  _options.timeout = TIMEOUT;
  return _options;
}

let _cache: Record<
  string,
  {
    nexts: Function[];
    inRequest?: boolean;
    data?: any;
  }
> = {};

export async function waitServer(url: string, params: Record<string, any>, next: Function, cacheKey?: string) {
  if (cacheKey) {
    if (!_cache[cacheKey]) _cache[cacheKey] = { nexts: [] };

    if (_cache[cacheKey].inRequest) {
      if (_cache[cacheKey].data) {
        return next(_cache[cacheKey].data);
      } else return _cache[cacheKey].nexts.push(next);
    }
    _cache[cacheKey].inRequest = true;
    _cache[cacheKey].nexts = [next];
  }
  try {
    const result = await server(url, params);
    if (cacheKey) {
      _cache[cacheKey].nexts.forEach((fn: Function) => fn(result));
      _cache[cacheKey].data = result;
      _cache[cacheKey].nexts = [];
    } else {
      next(result);
    }
  } catch (error) {
    if (cacheKey) {
      _cache[cacheKey].nexts = [];
    } else {
      next([]);
    }
  }
}
